//
//  YCCache.swift
//  YCNetworking
//
//  Created by YC on 2017/3/6.
//  Copyright © 2017年 YC. All rights reserved. mail:yangchong364@qq.com
//

import UIKit

class YCCache {
    static let shared = YCCache()
    private var cache: NSCache<AnyObject, AnyObject>
    
    private init() {
        cache = NSCache()
        cache.countLimit = kYCCacheCountLimit
    }
    
    //MARK: - public method
    func fetchCachedData(with serviceIdentifier:String, methodName: String, requestParams: Dictionary<String,Any>) -> Data? {
        return self.fetchCachedData(with: self.key(with: serviceIdentifier, methodName: methodName, requestParams: requestParams))
    }
    
    func saveCache(with data: Data, serviceIdentifier: String, methodName: String, requestParams: Dictionary<String,Any>) {
        self.saveCache(with: data, key: self.key(with: serviceIdentifier, methodName: methodName, requestParams: requestParams))
    }
    
    func deleteCache(with serviceIdentifier: String, methodName: String, requestParams: Dictionary<String,Any>) {
        self.deleteCache(with: self.key(with: serviceIdentifier, methodName: methodName, requestParams: requestParams))
        
    }
    
    func fetchCachedData(with key: String) -> Data? {
        var cachedObject: YCCachedObject
        if let object = self.cache.object(forKey: key as AnyObject) {
            cachedObject = object as! YCCachedObject
            
            if cachedObject.isOutdated || cachedObject.isEmpty {
                return nil
            }else {
                return cachedObject.content
            }
        }else {
            return nil
        }
        
    }
    
    func saveCache(with data: Data, key: String) {
        
        var cachedObject: YCCachedObject
        
        if let object = self.cache.object(forKey: key as AnyObject) {
            cachedObject = object as! YCCachedObject
        }else {
            cachedObject = YCCachedObject()
        }
        
        cachedObject.update(content: data)
        self.cache.setObject(cachedObject, forKey: key as AnyObject)
    }
    
    func deleteCache(with key: String) {
        self.cache.removeObject(forKey: key as AnyObject)
    }
    
    func clean() {
        self.cache.removeAllObjects()
    }
    
    func key(with serviceIdentifier: String, methodName: String, requestParams: Dictionary<String,Any>) -> String {
        return "\(serviceIdentifier)\(methodName)\(requestParams.YC_urlParamsString(signature: false))"
    }
}
